package com.mt.api.modules.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.mt.api.constants.constant.Constants;
import com.mt.api.constants.enums.AccountTypeEnum;
import com.mt.api.constants.enums.UserLevelEnum;
import com.mt.api.modules.domain.*;
import com.mt.api.modules.domain.bo.*;
import com.mt.api.modules.domain.dto.JwtUserDto;
import com.mt.api.modules.domain.vo.*;
import com.mt.api.modules.manager.*;
import com.mt.api.modules.mapper.AppBossMapper;
import com.mt.api.modules.mapstruct.AppBossMapStruct;
import com.mt.api.modules.mapstruct.AppBossSetupMapStruct;
import com.mt.api.modules.mapstruct.AppBrandMapStruct;
import com.mt.api.modules.mapstruct.BossPrinterMapStruct;
import com.mt.api.modules.service.IBossService;
import com.mt.api.util.JwtUserUtils;
import com.mt.common.response.WebResponse;
import com.mt.common.response.WebResponseUtils;
import lombok.RequiredArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author plover
 * @description 服务实现
 * @date 2020-07-06
 **/
@Service
@RequiredArgsConstructor
public class IBossServiceImpl extends ServiceImpl<AppBossMapper, AppBoss> implements IBossService {

    private final IBossBrandManager bossBrandManager;
    private final IBossManager bossManager;
    private final IBossSetupManager bossSetupManager;
    private final IBossPrinterManager bossPrinterManager;
    private final IBossRoleManager bossRoleManager;
    private final IBrandManager brandManager;
    private final IRoleManager roleManager;

    private final AppBrandMapStruct brandMapStruct;
    private final BossPrinterMapStruct bossPrinterMapStruct;
    private final AppBossMapStruct bossMapStruct;
    private final AppBossSetupMapStruct bossSetupMapStruct;

    @Override
    public WebResponse getBossList() {
        List<AppBossBrand> bossBrandList = bossBrandManager.getListByBrandId();
        List<Integer> bossIds = bossBrandList.stream().map(AppBossBrand::getBossId).collect(Collectors.toList());
        List<AppBoss> bossList = bossManager.listByIds(bossIds);
        List<AppBossVo> bossVoList = bossMapStruct.toVoList(bossList);
        for (AppBossVo bossVo : bossVoList) {
            AccountTypeEnum accountTypeEnum = AccountTypeEnum.ofCode(bossVo.getAccountType());
            if (Objects.nonNull(accountTypeEnum)) {
                bossVo.setAccountTypeText(accountTypeEnum.getName());
            }
        }
        return WebResponseUtils.successList(bossVoList);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public WebResponse addBoss(AppBossAddBo bo) {
        Integer bossId = JwtUserUtils.getJwtUser().getAppBoss().getId();
        AppBoss primaryBoss = bossManager.getById(bossId);
        Integer childAccountCount = primaryBoss.getChildAccountCount();
        if (Objects.isNull(primaryBoss)) {
            return WebResponseUtils.error("账号不存在");
        }
        AppBoss bossByPhone = bossManager.getBossByPhone(bo.getPhone());
        if (Objects.nonNull(bossByPhone)) {
            return WebResponseUtils.error("手机号已注册");
        }
        List<AppBossBrand> bossBrandList = bossBrandManager.getListByBrandId();
        List<Integer> bossIds = bossBrandList.stream().map(AppBossBrand::getBossId).collect(Collectors.toList());
        List<AppBoss> bossList = bossManager.listByIds(bossIds);
        int existChildAccountCount = bossList.stream().filter(appBoss -> Objects.equals(appBoss.getAccountType(), AccountTypeEnum.CHILD.getCode())).collect(Collectors.toList()).size();
        if (existChildAccountCount >= childAccountCount) {
            return WebResponseUtils.error("子账号已达到上限");
        }

        String salt = "";
        AppBoss boss = new AppBoss();
        boss.setAccount(StringUtils.isNotBlank(bo.getAccount()) ? bo.getAccount() : bo.getPhone());
        boss.setName(StringUtils.isNotBlank(bo.getName()) ? bo.getName() : bo.getPhone());
        boss.setPhone(bo.getPhone());
        // boss.setPassword(PasswordUtil.encryptPassword(bo.getPassword(), salt));
        // boss.setSalt(salt);
        boss.setAccountType(AccountTypeEnum.CHILD.getCode());
        boss.setUserLevel(UserLevelEnum.V3.getCode());
        boss.setRegDate(new Date());
        boss.setExpiryDate(primaryBoss.getExpiryDate());
        boss.setStatus(Constants.AccountState.NORMAL);
        bossManager.save(boss);

        AppBossBrand bossBrand = new AppBossBrand();
        bossBrand.setBossId(boss.getId());
        bossBrandManager.save(bossBrand);

        List<Integer> roleIdList = bo.getRoleIdList();
        if (CollectionUtils.isNotEmpty(roleIdList)) {
            List<BossRole> bossRoleList = roleIdList.stream().map(roleId -> {
                BossRole bossRole = new BossRole();
                bossRole.setBossId(boss.getId());
                bossRole.setRoleId(roleId);
                return bossRole;
            }).collect(Collectors.toList());
            bossRoleManager.saveBatch(bossRoleList);
        }
        return WebResponseUtils.success();
    }

    @Override
    public WebResponse editInfo(AppBossEditInfoBo bo) {
        AppBoss dbBoss = bossManager.getById(bo.getId());
        if (Objects.isNull(dbBoss)) {
            return WebResponseUtils.errorParam("账号不存在");
        }
        AppBoss boss = new AppBoss();
        boss.setId(bo.getId());
        boss.setAvatarUrl(bo.getAvatarUrl());
        boss.setName(bo.getName());
        bossManager.updateById(boss);
        return WebResponseUtils.success();
    }

    @Override
    public WebResponse editBoss(AppBossAddBo bo) {
        AppBoss dbBoss = bossManager.getById(bo.getId());
        if (Objects.isNull(dbBoss)) {
            return WebResponseUtils.errorParam("账号不存在");
        }
        AppBoss boss = new AppBoss();
        boss.setId(dbBoss.getId());
        boss.setAccount(StringUtils.isNotBlank(bo.getAccount()) ? bo.getAccount() : bo.getPhone());
        boss.setName(StringUtils.isNotBlank(bo.getName()) ? bo.getName() : bo.getPhone());
        boss.setPhone(bo.getPhone());
        // if (StringUtils.isNotEmpty(bo.getPassword())) {
        //     boss.setPassword(PasswordUtil.encryptPassword(bo.getPassword(), dbBoss.getSalt()));
        // }
        bossManager.updateById(boss);

        List<Integer> roleIdList = bo.getRoleIdList();
        if (CollectionUtils.isNotEmpty(roleIdList)) {
            List<BossRole> dbBossRoleList = bossRoleManager.getListByBossId(bo.getId());
            if (CollectionUtils.isNotEmpty(dbBossRoleList)) {
                List<Integer> ids = dbBossRoleList.stream().map(BossRole::getId).collect(Collectors.toList());
                bossRoleManager.removeByIds(ids);
            }
            List<BossRole> bossRoleList = roleIdList.stream().map(roleId -> {
                BossRole bossRole = new BossRole();
                bossRole.setBossId(boss.getId());
                bossRole.setRoleId(roleId);
                return bossRole;
            }).collect(Collectors.toList());
            bossRoleManager.saveBatch(bossRoleList);
        }
        return WebResponseUtils.success();
    }

    @Override
    public WebResponse<AppBossVo> bossDetail(Integer id) {
        AppBoss boss = bossManager.getById(id);
        AppBossVo bossVo = bossMapStruct.toVo(boss);
        List<BossRole> bossRoleList = bossRoleManager.getListByBossId(id);
        List<String> roleIds = bossRoleList.stream().map(bossRole -> bossRole.getRoleId().toString()).collect(Collectors.toList());
        bossVo.setRoleIdList(roleIds);
        return WebResponseUtils.success(bossVo);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public WebResponse delBoss(BossDelBo bo) {
        Integer id = bo.getId();
        AppBoss boss = bossManager.getById(id);
        if (Objects.isNull(boss)) {
            return WebResponseUtils.errorParam("账号不存在");
        }
        if (Objects.equals(AccountTypeEnum.PRIMARY.getCode(), boss.getAccountType())) {
            return WebResponseUtils.errorParam("主账号不能删除");
        }
        //删除账号
        bossManager.removeById(id);
        //删除账号品牌关系表
        AppBossBrand bossBrand = bossBrandManager.getBossBrandByBossId(id);
        if (Objects.nonNull(bossBrand)) {
            bossBrandManager.removeById(bossBrand.getId());
        }
        //删除账号角色关系表
        List<BossRole> bossRoleList = bossRoleManager.getListByBossId(id);
        if (CollectionUtils.isNotEmpty(bossRoleList)) {
            bossRoleManager.removeByIds(bossRoleList);
        }
        return WebResponseUtils.success();
    }

    @Override
    public WebResponse bossBrand() {
        JwtUserDto jwtUser = JwtUserUtils.getJwtUser();
        AppBossBrandVo appBossBrandVo = new AppBossBrandVo();

        Integer bossId = jwtUser.getAppBoss().getId();
        AppBoss boss = baseMapper.selectById(bossId);

        if (Objects.nonNull(boss)) {
            appBossBrandVo.setName(boss.getName());
            appBossBrandVo.setPhone(boss.getPhone());
        }
        //设置品牌信息
        AppBossBrand appBossBrand = bossBrandManager.getBossBrandByBossId(bossId);
        if (Objects.nonNull(appBossBrand)) {
            AppBrand brand = brandManager.getById(appBossBrand.getBrandId());
            if (Objects.nonNull(brand)) {
                appBossBrandVo.setHouseNo(brand.getHouseNo());
                appBossBrandVo.setBrandName(brand.getBrandName());
                appBossBrandVo.setMarket(brand.getMarketName());
            }
        }
        return WebResponseUtils.success(appBossBrandVo);
    }

    @Override
    public List<AppBoss> getAllByBrandId(Integer brandId) {
        AppBrand brand = brandManager.getById(brandId);
        if (Objects.nonNull(brand)) {
            List<AppBossBrand> appBossBrands = bossBrandManager.list(Wrappers.<AppBossBrand>lambdaQuery().eq(AppBossBrand::getBrandId, brand.getId()));
            List<Integer> bossIds = appBossBrands.stream().map(AppBossBrand::getBossId).collect(Collectors.toList());
            List<AppBoss> appBosses = bossManager.list(Wrappers.<AppBoss>lambdaQuery().in(AppBoss::getId, bossIds));
            return appBosses;
        }
        return null;
    }

    @Override
    public WebResponse getAccountTypeList() {
        List<JSONObject> results = Lists.newArrayList();
        for (AccountTypeEnum accountTypeEnum : AccountTypeEnum.values()) {
            JSONObject object = new JSONObject();
            object.put("code", accountTypeEnum.getCode());
            object.put("name", accountTypeEnum.getName());
            results.add(object);
        }
        return WebResponseUtils.successList(results);
    }

    @Override
    public WebResponse<AppBossInfoVo> bossInfo(BossInfoBo bo) {
        JwtUserDto jwtUser = JwtUserUtils.getJwtUser();
        Integer bossId = jwtUser.getAppBoss().getId();
        Integer brandId = JwtUserUtils.getJwtUser().getBrand().getId();
        AppBossInfoVo appBossInfoVo = new AppBossInfoVo();
        // 设置打印机信息
        BossPrinter bossPrinter = bossPrinterManager.getBossPrinterByBossId(bossId, bo.getOsType(), bo.getOsVersion());
        appBossInfoVo.setPrinter(bossPrinterMapStruct.toVo(bossPrinter));

        // 设置用户信息
        AppBoss boss = baseMapper.selectById(bossId);
        AppBossVo bossVo = bossMapStruct.toVo(boss);
        appBossInfoVo.setUserInfo(bossVo);

        // 设置品牌信息
        AppBrand brand = brandManager.getById(brandId);
        appBossInfoVo.setBrand(brandMapStruct.toVo(brand));

        AppBossSetup bossSetup = bossSetupManager.getBossSetupByBossId(bossId);
        appBossInfoVo.setSetup(bossSetupMapStruct.toVo(bossSetup));

        // 更新最后登录时间
        AppBoss upBoss = new AppBoss();
        upBoss.setId(bossId);
        upBoss.setLastLoginTime(new Date());
        return WebResponseUtils.success(appBossInfoVo);
    }
}